package it.crosato.stage.shared.objects;

import java.util.Vector;

public class Multiset {

	private Vector<MultisetElement> multiset = new Vector<MultisetElement>();
	
	public Multiset() {
		
	}
	
	/**
	 * Costruisce il multi-insieme a partire da un insieme con ripetizioni dato in ingresso
	 * @param elements l'insieme, con eventuali ripetizioni, da transformare in un multi-insieme
	 */
	public Multiset(Vector<String> elements) {
		Vector<String> copy = new Vector<String>();
		for (int i = 0; i < elements.size(); i++) {
			copy.add(elements.get(i));
		}
		while (copy.size() > 0) {
			String element = copy.remove(0);
			int cardinality = 1;
			for (int i = 0; i < copy.size(); i ++) {
				if (copy.get(i).equals(element)) {
					cardinality++;
					copy.remove(i);
					i--;
				}
			}
			multiset.add(new MultisetElement(element, cardinality));
		}
	}
	
	/**
	 * Ritorna il numero totale di elementi del multi-insieme
	 * @return il numero di elementi
	 */
	public int getNumberOfElements() {
		return multiset.size();
	}
	
	/**
	 * aggiunge un elemento al multi-insieme
	 * @param element l'elemento da aggiungere
	 */
	public void addMultisetElement(MultisetElement element) {
		multiset.add(element);
	}
	
	/**
	 * Ritorna l'i-esimo elemento del multi-insieme
	 * @param i l'indice dell'elemento
	 * @return l'elemento i-esimo o il valore nullo se l'indice non è corretto
	 */
	public MultisetElement getMultisetElement(int i) {
		if (i >= 0 && i < getNumberOfElements()) {
			return multiset.get(i);
		}
		else {
			return null;
		}
	}
	
	/**
	 * Ritorna la cardinalità del multi-insieme, ovvero la somma delle cardinalità
	 * dei suoi elementi
	 * @return la cardinalità dell'insieme
	 */
	public int getCardinality() {
		int cardinality = 0;
		for (int i = 0; i < multiset.size(); i++) {
			cardinality += multiset.get(i).getCardinality();
		}
		return cardinality;
	}
	
	/**
	 * Ritorna la cardinalità dell'intersezione tra il multi-insieme ed un altro.
	 * @param m il secondo multi-insieme
	 * @return la cardinalità dell'intersezione
	 */
	public int getIntersectionCardinality(Multiset m) {
		int cardinality = 0;
		for (int i = 0; i < getNumberOfElements(); i++) {
			MultisetElement me1 = getMultisetElement(i);
			boolean found = false;
			for (int j = 0; j < m.getNumberOfElements() && !found; j++) {
				MultisetElement me2 = m.getMultisetElement(j);
				if (me1.getElement().equals(me2.getElement())){
					if (me1.getCardinality() < me2.getCardinality()) {
						cardinality += me1.getCardinality();
					}
					else {
						cardinality += me2.getCardinality();
					}
					found = true;	
				}	
			}
		}
		return cardinality;
	}
}
